var roleBuilder = require('role.builder');
var roleHarvester = require('role.harvester');
var roleRepairer = require('role.repairer');
var roleTransporter = require('role.transporter');
var roleUpgrader = require('role.upgrader');
var oldTime = new Date().getTime();
var newTime = 0;
//var expectedBuilders = 1;
var expectedHarvestors = 2;
var expectedRepairers = 1;
var expectedTransporters = 1;
var expectedUpgraders = 1;

module.exports.loop = function () {
    
    //console.clear();

    newTime = new Date().getTime();
    console.log('Game Time is: ' + Game.time + ' (' + (newTime - oldTime) / 1000 + ' second)');
    oldTime = newTime;

    for(var name in Game.rooms) {
        console.log('Room "' + name + '" has ' + Game.rooms[name].energyAvailable + '/' + Game.rooms[name].energyCapacityAvailable + ' energy (' + (Game.rooms[name].energyAvailable / Game.rooms[name].energyCapacityAvailable) * 100 + '%)');
        console.log('Room "' + name + '" controller level is ' + Game.rooms[name].controller.level + ' , progress left ' + (Game.rooms[name].controller.progressTotal - Game.rooms[name].controller.progress) + ' (' + (Game.rooms[name].controller.progress / Game.rooms[name].controller.progressTotal) * 100 + '%)');
    }

    for(var name in Memory.creeps) {
        if(!Game.creeps[name]) {
            delete Memory.creeps[name];
            console.log('Clearing non-existing creep memory:', name);
        }
    }
    
    var tower1 = Game.getObjectById('5e4d0d0116258eea1732825d');
    if(tower1) {
        /*
        var closestDamagedStructure = tower1.pos.findClosestByRange(FIND_STRUCTURES, {
            filter: (structure) => structure.hits < structure.hitsMax
        });
        if(closestDamagedStructure) {
            tower1.repair(closestDamagedStructure);
        }
        */
        var closestHostile = tower1.pos.findClosestByRange(FIND_HOSTILE_CREEPS);
        if(closestHostile) {
            tower1.attack(closestHostile);
        }
    }

    var builders = _.filter(Game.creeps, (creep) => creep.memory.role == 'builder');
    var harvesters = _.filter(Game.creeps, (creep) => creep.memory.role == 'harvester');
    var repairers = _.filter(Game.creeps, (creep) => creep.memory.role == 'repairer');
    var transporters = _.filter(Game.creeps, (creep) => creep.memory.role == 'transporter');
    var upgraders = _.filter(Game.creeps, (creep) => creep.memory.role == 'upgrader');
    console.log('Creeps: ' + (builders.length + harvesters.length + repairers.length + transporters.length + upgraders.length) + 
            '    Builders: ' + builders.length +
            '    Harvesters: ' + harvesters.length  + '(' + expectedHarvestors + ')' + 
            '    Repairers: ' + repairers.length + '(' + expectedRepairers + ')' + 
            '    Transporters: ' + transporters.length + '(' + expectedTransporters + ')' + 
            '    Upgraders: ' + upgraders.length + '(' + expectedUpgraders + ')'
            );
    
    //800 Energy
    if(harvesters.length < expectedHarvestors) {
        var newName = 'Harvester' + Game.time;
        console.log('Spawning new Harvester: ' + newName);
        Game.spawns['Spawn1'].spawnCreep([WORK,WORK,WORK,WORK,CARRY,CARRY,CARRY,CARRY,CARRY,CARRY,MOVE,MOVE], newName,
            {memory: {role: 'harvester'}});
    }

    //800 Energy
    //no construction site no builder, 1 builder only, spawn when max energy
    const constructionTarget = Game.spawns['Spawn1'].pos.findClosestByRange(FIND_CONSTRUCTION_SITES);
    if(constructionTarget != null && builders.length == 0 && Game.rooms['W34N2'].energyAvailable == Game.rooms['W34N2'].energyCapacityAvailable) {
        var newName = 'Builder' + Game.time;
        console.log('Spawning new Builder: ' + newName);
        Game.spawns['Spawn1'].spawnCreep([WORK,WORK,WORK,WORK,CARRY,CARRY,CARRY,CARRY,CARRY,CARRY,MOVE,MOVE], newName,
        {memory: {role: 'builder'}});
    }

    //550 Energy
    if(repairers.length < expectedRepairers) {
        var newName = 'Repairers' + Game.time;
        console.log('Spawning new Repairers: ' + newName);
        Game.spawns['Spawn1'].spawnCreep([WORK,WORK,CARRY,CARRY,CARRY,CARRY,MOVE,MOVE,MOVE], newName,
            {memory: {role: 'repairer'}});
    }
    
    //150 Energy
    if(transporters.length < expectedTransporters) {
        var newName = 'Transporter' + Game.time;
        console.log('Spawning new Transporter: ' + newName);
        Game.spawns['Spawn1'].spawnCreep([CARRY,MOVE,MOVE], newName,
            {memory: {role: 'transporter'}});
    }

    //800 Energy
    if(upgraders.length < expectedUpgraders) {
        var newName = 'Upgrader' + Game.time;
        console.log('Spawning new Upgrader: ' + newName);
        Game.spawns['Spawn1'].spawnCreep([WORK,WORK,WORK,WORK,WORK,WORK,CARRY,MOVE,MOVE,MOVE], newName,
            {memory: {role: 'upgrader'}});
    }
    
    if(Game.spawns['Spawn1'].spawning) {
        var spawningCreep = Game.creeps[Game.spawns['Spawn1'].spawning.name];
        Game.spawns['Spawn1'].room.visual.text(
            '🛠️' + spawningCreep.memory.role,
            Game.spawns['Spawn1'].pos.x + 1,
            Game.spawns['Spawn1'].pos.y,
            {align: 'left', opacity: 0.8});
    }

    for(var name in Game.creeps) {
        var creep = Game.creeps[name];
        if(creep.memory.role == 'harvester') {
            roleHarvester.run(creep);
        }
        if(creep.memory.role == 'upgrader') {
            roleUpgrader.run(creep);
        }
        if(creep.memory.role == 'builder') {
            roleBuilder.run(creep);
        }
        if(creep.memory.role == 'transporter') {
            roleTransporter.run(creep);
        }
        if(creep.memory.role == 'repairer') {
            roleRepairer.run(creep);
        }
        if(creep.hits < creep.hitsMax) {
            creep.say('Help ME !');
            creep.moveTo(22,45);
        }
    }

    console.log();
}
